function MoveUp(oActive)
{
	switch (oActive.className)
	{
		case "section":
		
			if (oActive.previousSibling)
			{
				// swap the nodes in the xml
				//
				MoveUpAdjacentXml(GetSectionNode(oActive.name));
				
				// swap the nodes in the html
				//
				oActive.swapNode(oActive.previousSibling);
			}
		
			break;
			
		case "cell":
		
			if (oActive.parentElement.previousSibling.rowIndex > 0)
			{
				// if cell spans both columns or the next rows cell spans both columns move the whole row down
				//
				if ((oActive.parentElement.cells.length == 1) || (oActive.parentElement.previousSibling.cells.length == 1))
				{
					// swap the nodes in the xml
					//
					MoveUpAdjacentXml(GetRowNode(oActive.name));

					// swap the nodes in the html
					//
					oActive.parentElement.swapNode(oActive.parentElement.previousSibling);
				}
				else
				{
					// swap the nodes in the xml
					//
					var oNode = GetCellNode(oActive.name);
					
					var oParentNode		= oNode.parentNode;
					var oPrevParentNode	= oParentNode.previousSibling;
					var oNextParentNode;
					
					if (oNode.nextSibling)
					{
						oParentNode.insertBefore(oPrevParentNode.removeChild(oPrevParentNode.childNodes[0]), oNode.nextSibling);

						oNode = oPrevParentNode.childNodes[0];

						oParentNode		= oNode.parentNode;
						oNextParentNode	= oParentNode.nextSibling;

						oParentNode.insertBefore(oNextParentNode.removeChild(oNextParentNode.childNodes[0]), oNode);
					}
					else
					{
						oParentNode.insertBefore(oPrevParentNode.removeChild(oPrevParentNode.lastChild), null);

						oNode = oPrevParentNode.childNodes[0];

						oParentNode		= oNode.parentNode;
						oNextParentNode	= oParentNode.nextSibling;

						oParentNode.insertBefore(oNextParentNode.removeChild(oNextParentNode.lastChild.previousSibling), null);
					}
					
					PurgeEmptyRowsXml();

					// swap the nodes in the html
					//
					oActive.swapNode(oActive.parentElement.previousSibling.cells[oActive.cellIndex]);
					
					PurgeEmptyRowsHtml();
				}
			}
		
			break;
	}
}


function MoveDown(oActive)
{
	switch (oActive.className)
	{
		case "section":
		
			if (oActive.nextSibling)
			{						
				// swap the nodes in the xml
				//
				MoveDownAdjacentXml(GetSectionNode(oActive.name));
				
				// swap the nodes in the html
				//
				oActive.swapNode(oActive.nextSibling);
			}
		
			break;
			
		case "cell":
		
			if (oActive.parentElement.nextSibling)
			{
				// if cell spans both columns or the next rows cell spans both columns move the whole row down
				//
				if ((oActive.parentElement.cells.length == 1) || (oActive.parentElement.nextSibling.cells.length == 1))
				{
					// swap the nodes in the xml
					//
					MoveDownAdjacentXml(GetRowNode(oActive.name));
					
					// swap the nodes in the html
					//
					oActive.parentElement.swapNode(oActive.parentElement.nextSibling);
					
				}
				else
				{
					// swap the nodes in the xml
					//
					var oNode = GetCellNode(oActive.name);
					
					var oParentNode		= oNode.parentNode;
					var oNextParentNode	= oParentNode.nextSibling;
					var oPrevParentNode;

					if (oNode.nextSibling)
					{
						oParentNode.insertBefore(oNextParentNode.removeChild(oNextParentNode.childNodes[0]), oNode.nextSibling);

						oNode = oNextParentNode.childNodes[0];

						oParentNode		= oNode.parentNode;
						oPrevParentNode	= oParentNode.previousSibling;

						oParentNode.insertBefore(oPrevParentNode.removeChild(oPrevParentNode.childNodes[0]), oNode);
					}
					else
					{
						oParentNode.insertBefore(oNextParentNode.removeChild(oNextParentNode.lastChild), oNode);

						oNode = oNextParentNode.childNodes[0];

						oParentNode		= oNode.parentNode;
						oPrevParentNode	= oParentNode.previousSibling;

						oParentNode.insertBefore(oPrevParentNode.removeChild(oPrevParentNode.lastChild), null);
					}

					PurgeEmptyRowsXml();

					// swap the nodes in the html
					//
					oActive.swapNode(oActive.parentElement.nextSibling.cells[oActive.cellIndex]);

					PurgeEmptyRowsHtml();
				}
			}
		
			break;
	}
}


function MoveLeft(oActive)
{
	if (oActive.previousSibling)
	{
		switch (oActive.className)
		{
			case "tab tabOn":
				
				// swap the nodes in the xml
				//
				MoveUpAdjacentXml(GetTabNode(oActive.name));
		
				// swap the nodes in the html
				//
				oActive.swapNode(oActive.previousSibling);
			
				// move the glow on top of the tab
				//
				MoveTabHighlight(oActive);
			
				break;
				
			case "cell":
			
				// only pertains to cells that don't span both columns
				//
				if (oActive.parentElement.cells.length > 1)
				{
					// swap the nodes in the xml
					//
					if (oActive.name != "")
					{
						MoveUpAdjacentXml(GetCellNode(oActive.name));
					}
					else
					{
						MoveUpAdjacentXml(GetCellNode(oActive.previousSibling.name).nextSibling);
					}
			
					// swap the nodes in the html
					//
					oActive.swapNode(oActive.previousSibling);
				}
			
				break;
		}
	}
}


function MoveRight(oActive)
{
	if (oActive.nextSibling)
	{
		switch (oActive.className)
		{
			case "tab tabOn":
				
				// swap the nodes in the xml
				//
				MoveDownAdjacentXml(GetTabNode(oActive.name));
				
				// swap the nodes in the html
				//
				oActive.swapNode(oActive.nextSibling);
									
				// move the glow on top of the tab
				//
				MoveTabHighlight(oActive);

				break;
					
			case "cell":
				
				// only pertains to cells that don't span both columns
				//
				if (oActive.parentElement.cells.length > 1)
				{
					// swap the nodes in the xml
					//
					if (oActive.name != "")
					{
						MoveDownAdjacentXml(GetCellNode(oActive.name));
					}
					else
					{
						MoveDownAdjacentXml(GetCellNode(oActive.nextSibling.name).previousSibling);
					}

					// swap the nodes in the html
					//
					oActive.swapNode(oActive.nextSibling);
				}
				
				break;
		}
	}
}


// swaps node with previous node in xml
//
function MoveUpAdjacentXml(oNode)
{
	var oParentNode = oNode.parentNode;

	oParentNode.insertBefore(oParentNode.removeChild(oNode.previousSibling), oNode.nextSibling);
}


// swaps node with next node in xml
//
function MoveDownAdjacentXml(oNode)
{
	var oParentNode = oNode.parentNode;
	
	oParentNode.insertBefore(oParentNode.removeChild(oNode.nextSibling), oNode);
}


// removes all rows containing only empty cells from xml
//
function PurgeEmptyRowsXml()
{
	var oRows = oFormXml.selectNodes("/entity/form/tabs/tab/sections/section/rows/row[not(cell[0]/@name) and not(cell[1]/@name)]");

	var i;
	var iLen = oRows.length;

	// if we find one, strip it and jump out since there will never be more than one
	//
	for (i = 0; i < iLen; i++)
	{
		oRows[i].parentNode.removeChild(oRows[i])
		
		return;
	}
}


// removes all rows containing only empty cells from html
//
function PurgeEmptyRowsHtml()
{
	var i,ii,iii;
	
	var oTab;
	var oSection;
	var oRow;
	
	var iTabsLen = tabContent.children.length;
	var iSectionsLen;

	for (i = 0; i < iTabsLen; i++)
	{
		oTab = tabContent.children[i];
		
		iSectionsLen = oTab.children.length;
		
		for (ii = 0; ii < iSectionsLen; ii++)
		{
			oSection = oTab.children[ii];
			
			for (iii = 1; iii < oSection.rows.length; iii++)
			{
				oRow = oSection.rows[iii];
				
				// if we find one, strip it and jump out since there will never be more than one
				//
				if (oRow.cells[0].innerHTML == "")
				{
					if (oRow.cells.length == 1)
					{
						oRow.parentElement.deleteRow(oRow.rowIndex);
					
						return;
					}
					else if (oRow.cells[1].innerHTML == "")
					{
						oRow.parentElement.deleteRow(oRow.rowIndex);
					
						return;
					}
				}
			}
		}
	}
}
